"""
# nat-traversal

- udp打洞, 实现p2p通信

"""

import socket
import threading
import time
import sys
import tools


CODING_TYPE = 'utf-8'
peer_ip = peer_port = ""


def heartbeat():
    while True:
        msg = '%d|%s|%s' % (9,"keep ","live")
        udpSerSock.sendto(msg.encode(CODING_TYPE), server_addr)
        time.sleep(30)


def revMsg():
    global peer_ip,peer_port
    print(" start rev:")
    while True:
        data, addr = udpSerSock.recvfrom(1024)
        data = data.decode(CODING_TYPE)

        try:
            (msg_type,msg_arg1,msg_arg2)=str(data).split('|')
        except:
            print('[error msg!]', str(data))
            continue
        if int(msg_type)==9:
            continue
        elif int(msg_type)==0:
            print('[login success: %s]' % (str(data)))
        elif int(msg_type)==1:
            print("online hosts:\n%s"% (msg_arg1))
        elif int(msg_type)==2:
            print('[peer online] --- recv:', (msg_type,msg_arg1,msg_arg2))
            peer_ip=msg_arg1
            peer_port=msg_arg2
        elif int(msg_type)==3:
            print('[peer offline]')
        elif int(msg_type)==4:
            print('[respond peer]')
            msg = '%d|%s|%s' % (9,"hello"," ")
            udpSerSock.sendto(msg.encode(CODING_TYPE), (msg_arg1,int(msg_arg2)))
        elif int(msg_type)==5:
            print('[peer msg]:%s'% msg_arg1)
        else:
            print('[error Type!]', str(data))


if __name__ == '__main__':
    if sys.argv.__len__() == 1:
        # 房间名
        room_id = 9789
        print(f'未指定room_id, 将默认设置为{room_id}!')
    else:
        room_id = sys.argv[1]

    server_addr = ('192.168.0.103', 6000)

    udpSerSock= socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    # windows上需要绑定端口, 不然报错
    port = tools.get_a_not_in_use_port()
    udpSerSock.bind(('',port))

    Clinet_Name="clinet_A"

    try:
        rev_thread = threading.Thread(target = revMsg)
        rev_thread.setDaemon(True)
        rev_thread.start()

        heat_thread=threading.Thread(target = heartbeat)
        heat_thread.setDaemon(True)
        heat_thread.start()
    except:
        print("Error: unable to start thread")

        # ========================
    host_name="Noname"
    # 依次执行0，1，2，3命令后完成p2p连接并可以直接聊天
    while True:
        comd = input("Commend[0,1,2,3]>>")

        print(f'comd --- {comd}, {type(comd)}')
        # query online host
        if str(comd).strip()=='0':
            host_name = input("hostname>>")
            udpSerSock.sendto(('%d|%s|%s' % (0,str(host_name).strip()," ")).encode(CODING_TYPE), server_addr)
        elif str(comd).strip()=='1':
            print("get online host...")
            udpSerSock.sendto(('%d|%s|%s' % (1," "," ")).encode(CODING_TYPE), server_addr)
        elif str(comd).strip()=='2':
            peer_name = input("peer_name>>")
            print("get peer ip...")
            udpSerSock.sendto(('%d|%s|%s' % (2,str(peer_name).strip()," ")).encode(CODING_TYPE), server_addr)
        elif str(comd).strip()=='3':
            msg = input("Msg>>")
            udpSerSock.sendto(('%d|%s|%s' % (5,str(msg).strip()," ")).encode(CODING_TYPE), (peer_ip,int(peer_port)))
        if str(comd).strip()=='exit':
            print("exit!")
            break
    udpSerSock.close()

